#ifndef QTASK_H
#define QTASK_H

#include <QObject>
#include <QCoreApplication>
#include <QStringList>
#include <QTextStream>
#include <QSettings>
#include <QDir>

#include "Page.h"

#include "plogger.h"

class QTask : public QObject
{
    Q_OBJECT

public:

    //               MODO DI CHIAMARE GLI ARGOMENTI
    // Sono previsti i seguenti modi di chiamare il task
    // task                                 ==> switch mode INTERACTIVE
    // task -<command>                      ==> switch mode COMMAND
    // task -<command> <prj_name>           ==> switch mode COMMAND_PRJ
    // task -<command> <prj_name> <prj_ela> ==> switch mode COMMAND_ELA
    // task  <prj_name> <prj_ela>           ==> switch mode ARGUMENTS
    //
    //              ORGANIZZAZIONE DELLE DIRECTORIES
    //
    // prj +
    //     |----> .../prj_1/
    //     |----> .../prj_2/
    //     |----> .../prj_3/
    //     |---->    ...
    //     |----> .../prj_N/
    //
    // .../prj_N/ +
    //            |.../in/ +
    //                     |.../elab_1.dat
    //                     |.../elab_2.dat
    //                     |        ...
    //                     |.../elab_N.dat
    //
    //
    //            |.../out/ +
    //                      |.../elab_1/
    //                      |.../elab_2/
    //                      |     ...
    //                      |.../elab_N/
    //
    //


    enum Mode
    {
        INTERACTIVE = 1,
          ARGUMENTS = 2,
            COMMAND = 3,
        COMMAND_ELA = 4,
        COMMAND_PRJ = 5,
           ERR_MODE = 6
    };

    enum QuitRole
    {
        TASK  = 1,
        CHILD = 2
    };

    enum Channel
    {
        CH_STD = 1,
        CH_LOG = 2,
        CH_BOTH = 3
    };

    explicit QTask(QObject *parent = 0);
    QTask(QCoreApplication *app, QObject *parent = 0, const QString &application = "");
    ~QTask();

    QString  currentPrjName( void ) const;
    QString currentElabName( void ) const;

    const QStringList       &argv (void) const;
                  int nbArguments (void) const;

                 const Page &getMainPage (int* err = 0) const;

                 void lineOut (const QString &msg, Channel c = CH_STD);
              QString  lineIn (const QString &msg);

     // Legge il file di input e la salva nella cache
     bool readMainPage ( void );

     // Utility che salva la pagina su file esterno come file di testo
     bool savePage (
             const Page &p,
             const QString &file_name,
             const QString &sub = QString()
             );

     // Utility che salva una pagina di log
     bool saveLogPage ( const Page &p );

//    void setRunningMode (Mode m);

public slots:
    void run ( void );
    void msgExit ( void );
    void aboutToQuit ( void );

signals:
    void finished( void ); // serve a terminare il processo

protected:
    virtual bool runInteractive (QuitRole role = TASK);
    virtual bool runArguments   (QuitRole role = TASK);
    virtual void quit (); // Emette finished esplicitamente

    enum Cmd
    {
        CMD_UNKNOWN = 1,
        CMD_QUIT    = 2,
        CMD_YES     = 3,
        CMD_NO      = 4
    };
    virtual  Cmd parseLine     ( const QString &line, bool *ok );
    virtual bool performAction ( int cmd );

    static bool removeDir(const QString &dirName);

private:
       void  m_setupConnections();

          QCoreApplication *m_app;
    const      QStringList  m_argv_list;
                       int  m_argv_nb;

    QTextStream m_cin;
    QTextStream m_cout;

       Mode  m_mode;
       Mode  m_swichMode();
    PLogger *m_logger;

    // Setting for USER
    QSettings* m_settingsUser;
    bool m_readSettingsUser( void );
    QString m_INI_user_config_filename;

    QString m_cmd_name;  // Nome del comando
    QString m_prj_name;  // Nome del progetto
    QString m_elab_name; // Nome dell'elaborazione


    QString  m_dir_in_name; // Nome della directory di input (di solito "in")
    QString m_dir_out_name; // Nome della directori di output (di solito "out")

    QDir m_exe_dir; // Directory dell'eseguibile
    QDir m_bin_dir; // Directory dei binari
    QDir m_src_dir; // Directory delle risorse
    QDir m_prj_dir; // Directory dei progetti

    QStringList m_src_paths; // Lista directories contenute in <src>
    QStringList m_out_paths; // Lista directories contenute in <out>

    QDir  m_prjc_dir;     // Directory del progetto corrente
    QDir  m_prjc_in_dir;  // Directory  input del progetto corrente
    QDir  m_prjc_out_dir; // Directory output del progetto corrente
    QDir  m_elab_out_dir; // Directory output dell'elaborazione corrente

    // Files utente
    QFile m_elab_file;    // File dell'elaborazione

    // Files creati
    QStringList m_files_created;

    bool m_act_noAction();
    bool m_act_exit();

    enum SettingsUser
    {
        SET_RO_WHEN_OUT_EXISTS_EXIT  = 0,
        SET_RO_WHEN_OUT_EXISTS_CLEAN = 1
    };

    SettingsUser m_settings_when_out_exist;

    ////////////////////////////////////////
    Page m_mainPage;
};

#endif // QTASK_H
